home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Freeware 1998 June
/
SGI Freeware 1998 June.iso
/
dist
/
fw_UMINNgopher.idb
/
usr
/
freeware
/
src
/
gopher_1.12
/
gopherd
/
daemon.c.z
/
daemon.c
Wrap
C/C++ Source or Header
|
1997-09-09
|
4KB
|
190 lines
/********************************************************************
* $Author: drich $
* $Revision: 1.1 $
* $Date: 1995/10/03 04:08:23 $
* $Source: /proj/freeware1.0/gopher1.12/src/gopherd/RCS/daemon.c,v $
* $Status: $
*
* Paul Lindner, University of Minnesota CIS.
*
* Copyright 1991, 1992 by the Regents of the University of Minnesota
* see the file "Copyright" in the distribution for conditions of use.
*********************************************************************
* MODULE: daemon.c
* Routines to detach from and run as a daemon.
*********************************************************************
* Revision History:
* $Log: daemon.c,v $
* Revision 1.1 1995/10/03 04:08:23 drich
* gopher 1.2 check-in
*
* Revision 1.1 1992/12/10 23:13:27 lindner
* gopher 1.1 release
*
*
*********************************************************************/
#include "gopherd.h"
#if defined(_AIX) /** AIX needs bsd signals. **/
#define _BSD
#endif
/*
* A BSD style SIGCLD signal handler that can be used by a server
* that's not interested in its child's exit status, but needs to
* wait for them, to avoid clogging up the system with zombies.
*
* Beware that the calling process may get an interrupted system
* call when we return, so they had better handle that.
*
* (From Stevens pg 82)
*/
#include "Wait.h"
/* some machines don't have SIGCLD defined */
#ifndef SIGCLD
#define SIGCLD SIGCHLD
#endif
#ifdef hpux
#define TIOCNOTTY _IO('t', 113) /* void tty association */
#endif
void
sig_child()
{
/*
* Use the wait3() system call with the WNOHANG option
*/
int pid;
Portawait status;
while ( (pid = wait3(&status, WNOHANG|WUNTRACED, NULL)) > 0)
;
}
#include <stdio.h>
#include <sys/param.h>
#include <errno.h>
extern int errno;
#if defined(SIGTSTP) && !defined(M_XENIX) && !defined(USG)/* True on a BSD system */
#include <sys/file.h>
#include <sys/ioctl.h>
#endif
/*
* Detach a daemon process from login session context
*/
void
daemon_start(ignsigcld)
int ignsigcld; /* Nonzero -> nuke zombie children */
{
register int childpid, fd;
/*
* If we were started by init (process 1) from the /etc/inittab
* file there's no need to detach.
*/
if (getppid() != 1) {
#ifdef SIGTTOU
signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
#endif
/*
* If we were not started in the background, fork and let
* the parent exit. This also guarantees the first child
* is not a process group leader.
*/
if ( (childpid = fork()) < 0)
err_sys("can't fork first child");
else if (childpid >0)
exit(0); /* parent */
/*
* First Child process
*
* Disassociate from controlling terminal and process group.
* Ensure the process can't reacquire a new controlling terminal
*/
#if defined(SIGTSTP) && !defined(USG) /* BSD */
#if defined(hpux) || defined(_SEQUENT_) || defined(_CRAY) || defined(USG)
setsid();
#else
if (setpgrp(0, getpid()) == -1)
err_sys("can't change process group");
if ( (fd = uopen("/dev/tty", O_RDWR)) >= 0) {
ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling TTY*/
close(fd);
}
#endif /* hpux et al.*/
#else /* System V */
if (setpgrp() == -1)
err_sys("Can't change process group");
signal(SIGHUP, SIG_IGN); /* immune from pgrp leader death */
if ( (childpid = fork()) < 0)
err_sys("Can't fork second child");
else if (childpid > 0)
exit(0); /* First child */
/* second child */
#endif
} /* End of if test for ppid == 1 */
/** Close any file descriptors **/
for (fd = 0; fd < NOFILE; fd++)
close(fd);
errno = 0; /* probably set to EBADF from a close */
/** Change the current directory to / **/
/* No need for this, since we're already where we want to be */
/* rchdir("/"); */
/** Clear inherited file mode creation mask. **/
umask(0);
/*
* See if the caller isn't ineterested in the exit status of its
* children, and doesn't want to have them become zombies
*/
if (ignsigcld) {
#if defined(SIGCLD) && !defined(_CRAY) && !defined(USG)
void sig_child();
signal(SIGCLD, sig_child); /* BSD */
#else
signal(SIGCLD, SIG_IGN); /* System V */
#endif
}
}